using System;
using System.Collections.Generic;
using System.Diagnostics;
using Sedge.Core.Execution.ReportElements;
using Sedge.Core.Globalization;

namespace Sedge.Core.Configuration.Report
{
	public class ProcessesSource : IDataSource
	{
		private Suite _suite;

		public string Caption { get; set; }
		public Options Options { get; set; }

		public void PrepareSource(Suite suite)
		{
			_suite = suite;
		}

		public List<IReportElement> GetReportElements()
		{
			ReportTable table = new ReportTable(_suite) { Header = Caption };
			table.SetHeader(new[]
			                {
			                	Locale.TemplateStrings.ProcessesProcessCol, Locale.TemplateStrings.ProcessesMemoryCol,
			                	Locale.TemplateStrings.ProcessesThreadsCol, Locale.TemplateStrings.ProcessesUptimeCol,
			                	Locale.TemplateStrings.ProcessesVersionCol, Locale.TemplateStrings.ProcessesDescriptionCol
			                });

			Process[] processes = Process.GetProcesses();
			foreach (Process process in processes)
			{
				List<string> row;
				try
				{
					string name = String.Concat(process.ProcessName, process.Responding ? String.Empty : "(not responding)");
					string fileVersion = String.Empty;
					string fileComments = String.Empty;
					if (process.MainModule != null)
					{
						fileVersion = process.MainModule.FileVersionInfo.FileVersion;
						fileComments = process.MainModule.FileVersionInfo.FileDescription;
					}

					row = new List<string>
					      {
					      	name,
								String.Format("{0} K", process.PrivateMemorySize64 / 1024.0),
					      	Convert.ToString(process.Threads.Count), 
								CalculateUptime(process.StartTime),
								fileVersion, 
								fileComments
					      };
				}
				catch (Exception)
				{
					row = null;
				}

				if (row != null)
					table.AddRow(row);

			}

			return new List<IReportElement> { table };
		}

		private static string CalculateUptime(DateTime startTime)
		{
			TimeSpan timeSpan = DateTime.Now.Subtract(startTime);

			return String.Format("{0:D2}:{1:D2}:{2:D2}", timeSpan.Hours, timeSpan.Minutes % 60, timeSpan.Seconds % 60);
		}
	}
}